# coding=utf-8
"""
mongo connector
Author: kaspar
Date: 2022-04-05
"""
import threading
import random
from pymongo import MongoClient, ASCENDING
from util.config import Config
from util.logger import Logger

class myMongo(object):
    """
    mongo class
    """
    myMongo_instance = None
    myMongo_mutex = threading.RLock()
    def __init__(self):
        """
        init function
        """
        self._db_address = Config.get_conf('db_mongo', 'db_address')
        self._mongo_max_retry = int(Config.get_conf('db_mongo', 'db_max_retry'))
        self._mongo_client = None

    @staticmethod
    def connect():
        """
        connect
        """
        myMongo.myMongo_instance._mongo_client = MongoClient(myMongo.myMongo_instance._db_address, connect=False)

    @staticmethod
    def check_connect_once():
        """
        check connect once
        """
        try:
            if myMongo.myMongo_instance._mongo_client is None:
                myMongo.connect()
            return 0
        except Exception as e:
            Logger.writelog("error", "mongo connent reconnet error: %s"\
                % str(e))
            myMongo.connect()
            return -1

    @staticmethod
    def check_connect():
        """
        reconnect
        """
        try_index = 0
        while try_index < myMongo.myMongo_instance._mongo_max_retry:
            try_index += 1
            connent_flag = myMongo.check_connect_once()
            if 0 == connent_flag:
                return

    @staticmethod
    def get_instance():
        """
        get mymongo instance
        """
        if (myMongo.myMongo_instance is None):
            myMongo.myMongo_mutex.acquire()
            if (myMongo.myMongo_instance is None):
                myMongo.myMongo_instance = myMongo()
                myMongo.check_connect()
            myMongo.myMongo_mutex.release()
        return myMongo.myMongo_instance._mongo_client

class HandlerMongoDb(object):
    """
    handler mongodb
    """
    def __init__(self):
        self._mongo = myMongo.get_instance()[Config.get_conf('db_mongo', 'db_database')]

    def insert_one(self, collection, data):
        assert isinstance(data, dict)
        self._mongo[collection].insert_one(data)
        Logger.writelog('info', 'insert {} success'.format(collection))

    def find_one(self, collection, condition):
        assert isinstance(condition, dict)
        res = self._mongo[collection].find_one(condition)
        return res

    def random_find_one(self, collection):
        random_no = random.randint(0, self.cnt(collection) - 1)
        res = self._mongo[collection].find().skip(random_no).limit(1)
        return res[0]

    def find(self, collection, condition):
        assert isinstance(condition, dict)
        res = self._mongo[collection].find(condition).sort('timestamp', ASCENDING)
        return res

    def update_one(self, collection, condition, data):
        pass

    def delete_one(self, collection, condition):
        assert isinstance(condition, dict)
        res = self._mongo[collection].delete_one(condition)
        return res.deleted_count == 1

    def list_collections(self):
        return self._mongo.list_collection_names()

    def cnt(self, collection):
        res = self._mongo[collection].estimated_document_count()
        return res

def test():
    a = HandlerMongoDb()
    # print(a.list_collections())
    #
    web = {
        'url': 'https://youquhome.com/1',
        'desp': '描述xxx',
        'time': 'timestamp'
    }
    # b = a.insert_one('website', web)
    # print(b)
    res = a.find_one('website', {'no': 100})
    # a.delete_one('website', {'2':'local'})
    print(res)

if __name__ == '__main__':
    test()